package ar.Location.Map;

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import ar.Location.Constant.Define;
import ar.Location.Helper.BitmapProvider;
import ar.activity.R.string;
import ar.activity.DirectionsActivity;
import ar.globals.Globals;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
import com.google.android.maps.Overlay;

public class EnhancedMapView extends MapView {

	private static final String TAG = "EnhancedMapView";

	public static GeoPoint myLocation = null;
	public static GeoPoint lastMapCenter;
	public static boolean MODE_TRACKING_ON_MAP = false;
	public static int lastZoomLevel = -1;

	public Timer longpressTimer = new Timer();
	public OnLongPressListener longpressListener;

	public Context mapViewContext = null;
	public Drawable normalMarker = null;

	public MyGeocoder myGeoCoder = null;
	public List<Overlay> listOverlays = null;
	public MapController mapController = null;
	public MyLocationOverlay myLocationOverlay = null;

	static MapOverlay mapOverlay = null;
	static InterestingLocations interestingLocations = null;
	static SharingLocations sharingLocations = null;

	Resources res = null;
	
	public ArrayList<MyOverlayItem> getListMarkers() {
		return interestingLocations.getListMarkers();
	}

	public EnhancedMapView(Context context, AttributeSet attSet) {

		super(context, attSet);

		normalMarker = BitmapProvider.normalMarker;

		mapViewContext = context;
		res = context.getResources();
		mapOverlay = new MapOverlay(this, context);
		mapController = getController();
		myGeoCoder = new MyGeocoder(mapViewContext);
		myLocationOverlay = new MyLocationOverlay(context, this);

		if (interestingLocations == null) {
			interestingLocations = new InterestingLocations(this,
					mapViewContext, normalMarker);
		} else {
			interestingLocations.initContext(this, context);
			interestingLocations.refreshListMarkers();
			interestingLocations.initPopUpMarker(this, context);
		}

		if (sharingLocations == null) {
			sharingLocations = new SharingLocations(this, mapViewContext,
					normalMarker);
		} else {
			sharingLocations.initContext(this, context);
			sharingLocations.refreshListMarkers();
			sharingLocations.initPopUpMarker(this, context);
		}

		listOverlays = getOverlays();
		listOverlays.add(myLocationOverlay);
		listOverlays.add(mapOverlay);
		listOverlays.add(interestingLocations);
		listOverlays.add(sharingLocations);

		updatePosition();
	}

	public void updatePosition() {
		if (lastMapCenter != null) {
			setCenter(lastMapCenter);
		} else {

			goToMyLocation();
			/*
			 * mapController.setZoom(15); myLocationOverlay.runOnFirstFix(new
			 * Runnable() { public void run() { goToMyLocation(); } });
			 */
		}

		if (lastZoomLevel == -1) {
			mapController.setZoom(15);
		} else {
			mapController.setZoom(lastZoomLevel);
		}
	}

	public void updateRoad() {
		mapOverlay.updateRoad();
	}

	public void addOverlays(Overlay overlay) {
		listOverlays.add(overlay);
	}

	public void removeOverlay(Overlay overlay) {
		if (overlay != null) {
			listOverlays.remove(overlay);
		}
	}

	public void clearListOverlays() {
		listOverlays.clear();
	}

	@Override
	protected void dispatchDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.dispatchDraw(canvas);
		lastZoomLevel = getZoomLevel();
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {

		int top = getTop();
		int left = getLeft();
		Log.d(TAG, "Map) top: " + top + ", left: " + left);

		if (Globals.markers.size() > 0) {
			MyOverlayItem myMarker = Globals.markers.get(0);
			Point p = new Point();
			if (myMarker != null) {
				p = getProjection().toPixels(myMarker.getPoint(), p);
			}
			Log.d(TAG, "Marker0 pos: X = " + p.x + ", Y = " + p.y);
		}

		Log.d(TAG,
				"Touch on pos: X = " + event.getX() + ", Y = " + event.getY());

		onLongTouchEvent(event);
		return super.onTouchEvent(event);
	}

	private void onLongTouchEvent(final MotionEvent event) {

		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN: {
			if (!DirectionsActivity.modeDirections) {
				longpressTimer = new Timer();
				longpressTimer.schedule(new TimerTask() {
					@Override
					public void run() {
						GeoPoint longpressLocation = getProjection()
								.fromPixels((int) event.getX(),
										(int) event.getY());

						longpressListener.onLongPress(EnhancedMapView.this,
								longpressLocation);
					}

				}, Define.LONGPRESS_THRESHOLD);

				updateLastMapCenter();
			}
		}
			break;

		case MotionEvent.ACTION_MOVE: {
			if (!getMapCenter().equals(lastMapCenter)) {
				longpressTimer.cancel();
			}

			updateLastMapCenter();
		}
			break;
		case MotionEvent.ACTION_UP: {
			if (DirectionsActivity.modeDirections) {
				if (Globals.markers != null) {
					clearMarkers();

					GeoPoint choosePoint = getProjection().fromPixels(
							(int) event.getX(), (int) event.getY());

					if (DirectionsActivity.chooseStartPoint) {
						DirectionsActivity.startPoint = choosePoint;
					} else {
						if (DirectionsActivity.chooseEndPoint) {
							DirectionsActivity.endPoint = choosePoint;
						}
					}

					if (DirectionsActivity.startPoint != null) {
						MyOverlayItem overlayStartPoint = new MyOverlayItem(
								DirectionsActivity.startPoint, res.getString(string.hintStartPoint),
								res.getString(string.tapToSelect));
						overlayStartPoint
								.setMarker(BitmapProvider.directionMarker);
						addMarker(overlayStartPoint);
					}
					if (DirectionsActivity.endPoint != null) {
						MyOverlayItem overlayEndPoint = new MyOverlayItem(
								DirectionsActivity.endPoint, res.getString(string.hintEndPoint),
								res.getString(string.tapToSelect));
						overlayEndPoint
								.setMarker(BitmapProvider.directionMarker);
						addMarker(overlayEndPoint);
					}

					interestingLocations.showPopUpMarker(0);
				}
			}

			longpressTimer.cancel();
		}
			break;
		}

		if (event.getPointerCount() > 1) {
			longpressTimer.cancel();
		}
	}

	public void updateLastMapCenter() {
		lastMapCenter = getMapCenter();
	}

	public void setOnLongpressListener(OnLongPressListener listener) {
		longpressListener = listener;
	}

	public void goToMyLocation() {
		/*
		 * if (myLocationOverlay != null) { myLocation =
		 * myLocationOverlay.getMyLocation(); if (myLocation != null) {
		 * mapController.animateTo(myLocation); } }
		 */
		myLocation = Globals.getMyLocation();
		if (myLocation != null) {
			mapController.animateTo(myLocation);
		}
	}

	public void setMyCenter() {
		myLocation = myLocationOverlay.getMyLocation();
		if (myLocation != null) {
			mapController.setCenter(myLocation);
		}
	}

	public void zoomIn() {
		mapController.zoomIn();
	}

	public void zoomOut() {
		mapController.zoomOut();
	}

	public void setZoom(int level) {
		// TODO Auto-generated method stub
		mapController.setZoom(level);
	}

	public void setCenter(GeoPoint geoPoint) {
		// TODO Auto-generated method stub
		mapController.setCenter(geoPoint);
	}

	public MyOverlayItem search(GeoPoint location) {
		// TODO Auto-generated method stub
		return myGeoCoder.search(location);
	}

	public MyOverlayItem search(String locationName) {
		// TODO Auto-generated method stub
		return myGeoCoder.search(locationName);
	}

	public void showLatestPopUpMarker() {
		// TODO Auto-generated method stub
		if (interestingLocations != null && interestingLocations.size() > 0) {
			interestingLocations
					.showPopUpMarker(interestingLocations.size() - 1);
		}
	}

	public void addSharingLocation(MyOverlayItem myOverlayItem) {
		// TODO Auto-generated method stub
		sharingLocations.addMarker(myOverlayItem);
	}

	public void clearSharingLocations() {
		// TODO Auto-generated method stub
		sharingLocations.clearMarker();
	}

	public void addMarker(MyOverlayItem myOverlayItem) {
		// TODO Auto-generated method stub
		interestingLocations.addMarker(myOverlayItem);
	}

	public void clearMarkers() {
		// TODO Auto-generated method stub
		interestingLocations.clearMarker();
	}

	public void clearRoute() {
		// TODO Auto-generated method stub
		mapOverlay.clearRoute();
	}

	public void enableCompass() {
		myLocationOverlay.enableCompass();
	}

	public void disableCompass() {
		myLocationOverlay.disableCompass();
	}

	public void enableMyLocation() {
		myLocationOverlay.enableMyLocation();
	}

	public void disableMyLocation() {
		myLocationOverlay.disableMyLocation();
	}

	public void refreshListMarkers() {
		interestingLocations.refreshListMarkers();
	}

	public void clear() {
		// TODO Auto-generated method stub
		clearMarkers();
		clearSharingLocations();
		clearRoute();
	}
}
